package com.iacrqq.sedaf.application.adaptive;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

import com.iacrqq.sedaf.common.Controllable;
import com.iacrqq.sedaf.common.Initializable;
import com.iacrqq.sedaf.config.Configuration;
import com.iacrqq.sedaf.queue.adaptive.QueueAdjuster;
import com.iacrqq.sedaf.stage.adaptive.StageAdjuster;

/**
 * 
 * @author sihai
 *
 */
public class ApplicationAdjuster implements Initializable, Controllable
{
	public static int DEFAULT_ADJUST_HISTORY = 10;		//
	public static int DEFAULT_ADJUST_INTERVAL = 10;		//	seconds 
	
	private List<StageAdjuster> stageAdjusterList = new LinkedList<StageAdjuster>();
	private List<QueueAdjuster> queueAdjusterList = new LinkedList<QueueAdjuster>();
	
	private ScheduledExecutorService adjustScheduler;
	
	@Override
	public void init(Configuration config) throws Exception
	{
		adjustScheduler = Executors.newScheduledThreadPool(1, new ThreadFactory()
		{
			public Thread newThread(Runnable r)
			{
				return new Thread(r, "ApplicationAdjuster");
			}
		});
	}
	
	@Override
	public void start()
	{
		adjustScheduler.scheduleAtFixedRate(new AdjustTask(), DEFAULT_ADJUST_INTERVAL, DEFAULT_ADJUST_INTERVAL, TimeUnit.SECONDS);
	}

	@Override
	public void pause()
	{
		
	}

	@Override
	public void stop()
	{
		adjustScheduler.shutdown();
	}
	
	public void addStageAdjuster(StageAdjuster stageAdjuster)
	{
		stageAdjusterList.add(stageAdjuster);
	}
	
	public void addQueueAdjuster(QueueAdjuster queueAdjuster)
	{
		queueAdjusterList.add(queueAdjuster);
	}
	
	private void _ajust_()
	{
		for(QueueAdjuster queueAdjuster : queueAdjusterList)
		{
			queueAdjuster.adjust();
		}
		
		for(StageAdjuster stageAdjuster : stageAdjusterList)
		{
			stageAdjuster.adjust();
		}
	}
	
	private class AdjustTask implements Runnable
	{
		@Override
		public void run()
		{
			_ajust_();
		}
	}
}
